﻿using Microsoft.EntityFrameworkCore;
using StudentInfoSystem.Core.Data.DbContexts;
using StudentInfoSystem.Core.Interfaces;
using StudentInfoSystem.Core.Models;
using StudentInfoSystem.Core.Models.Enums;
using StudentInfoSystem.Core.Utils;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace StudentInfoSystem.Core.MockImplementations;

public class MockStudentService : IStudentService
{
    private readonly AppDbContext _context;
    private SearchCriteria? _currentSearchCriteria;
    private SortOption? _currentSortOption;
    private bool _isSortAscending = true;
    private bool _disposed = false;

    public MockStudentService(AppDbContext context)
    {
        _context = context;
        _context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
        _context.ChangeTracker.AutoDetectChangesEnabled = false;

        // 异步确保数据库创建并初始化数据
        InitializeDatabaseAsync().Wait(); // 注意：在构造函数中等待异步方法
    }

    private async Task InitializeDatabaseAsync()
    {
        // 确保数据库创建
        await _context.Database.EnsureCreatedAsync();

        // 检查是否存在数据
        if (!_context.Students.Any())
        {
            // 生成100个随机学生数据
            var students = StudentDataGenerator.GenerateRandomStudents(100);
            await _context.Students.AddRangeAsync(students);
            await _context.SaveChangesAsync();
        }
    }
    public List<Student> GetAll()
    {
        return ExecuteWithPerformanceMonitoring(() =>
            _context.Students.AsNoTracking().ToList());
    }

    public Student? GetById(string studentId)
    {
        return ExecuteWithPerformanceMonitoring(() =>
            _context.Students
                .AsNoTracking()
                .FirstOrDefault(s => s.Id == studentId));
    }

    public void Add(Student student)
    {
        ExecuteWithConcurrencyControl(() =>
        {
            if (_context.Students.Any(s => s.Id == student.Id))
                throw new InvalidOperationException("学号已存在");

            _context.Students.Add(student);
            SaveStudents();
        });
    }

    public void Update(Student student)
    {
        ExecuteWithConcurrencyControl(() =>
        {
            var existing = _context.Students
                .AsTracking()
                .FirstOrDefault(s => s.Id == student.Id);

            if (existing == null)
                throw new KeyNotFoundException("学生不存在");

            _context.Entry(existing).CurrentValues.SetValues(student);
            SaveStudents();
        });
    }

    public void Delete(string studentId)
    {
        ExecuteWithConcurrencyControl(() =>
        {
            var student = _context.Students
                .AsTracking()
                .FirstOrDefault(s => s.Id == studentId);

            if (student != null)
            {
                _context.Students.Remove(student);
                SaveStudents();
            }
        });
    }

    public void Search(SearchCriteria criteria)
    {
        _currentSearchCriteria = criteria;
    }

    public void Sort(SortOption sortOption, bool isAscending)
    {
        _currentSortOption = sortOption;
        _isSortAscending = isAscending;
    }

    public IEnumerable<Student> GetAllFiltered()
    {
        return ExecuteWithPerformanceMonitoring(() =>
        {
            var query = _context.Students.AsNoTracking().AsQueryable();

            // 应用搜索条件
            if (_currentSearchCriteria?.Field != null &&
                !string.IsNullOrEmpty(_currentSearchCriteria.Keyword))
            {
                query = _currentSearchCriteria.Field switch
                {
                    SearchField.StudentId => query.Where(s => s.Id.Contains(_currentSearchCriteria.Keyword)),
                    SearchField.Name => query.Where(s => s.Name.Contains(_currentSearchCriteria.Keyword)),
                    SearchField.College => query.Where(s => s.College.Contains(_currentSearchCriteria.Keyword)),
                    SearchField.Department => query.Where(s => s.Department.Contains(_currentSearchCriteria.Keyword)),
                    SearchField.Class => query.Where(s => s.Class.Contains(_currentSearchCriteria.Keyword)),
                    SearchField.Dormitory => query.Where(s => s.Dormitory.Contains(_currentSearchCriteria.Keyword)),
                    SearchField.Hometown => query.Where(s => s.Hometown.Contains(_currentSearchCriteria.Keyword)),
                    _ => query
                };
            }

            // 应用排序条件
            if (_currentSortOption != null)
            {
                query = (_currentSortOption, _isSortAscending) switch
                {
                    (SortOption.ByStudentId, true) => query.OrderBy(s => s.Id),
                    (SortOption.ByStudentId, false) => query.OrderByDescending(s => s.Id),
                    (SortOption.ByCollege, true) => query.OrderBy(s => s.College),
                    (SortOption.ByCollege, false) => query.OrderByDescending(s => s.College),
                    (SortOption.ByDormitory, true) => query.OrderBy(s => s.Dormitory),
                    (SortOption.ByDormitory, false) => query.OrderByDescending(s => s.Dormitory),
                    (SortOption.ByDepartment, true) => query.OrderBy(s => s.Department),
                    (SortOption.ByDepartment, false) => query.OrderByDescending(s => s.Department),
                    (SortOption.ByClass, true) => query.OrderBy(s => s.Class),
                    (SortOption.ByClass, false) => query.OrderByDescending(s => s.Class),
                    _ => query
                };
            }

            return query.ToList();
        });
    }

    public void SaveStudents()
    {
        ExecuteWithConcurrencyControl(() =>
        {
            _context.ChangeTracker.DetectChanges();
            _context.SaveChanges();
        });
    }

    public void LoadStudents(string filePath)
    {
        // 占位实现 - 实际项目中应添加文件导入逻辑
        throw new NotImplementedException("数据库加载功能需实现文件导入");
    }

    public void DeleteStudents(string filePath)
    {
        ExecuteWithConcurrencyControl(() =>
        {
            _context.Students.ExecuteDelete();
            _context.SaveChanges();
        });
    }

    public void ExportDatabase(string filePath, ExportFormat format)
    {

    }

    private void ExportToSQLite(AppDbContext sourceContext, string targetFilePath)
    {
        // 如果目标文件已存在，先删除
        if (File.Exists(targetFilePath))
        {
            File.Delete(targetFilePath);
        }

        // 使用SQLite的备份API复制数据库
        sourceContext.Database.ExecuteSqlRaw($"VACUUM INTO '{targetFilePath}'");
    }

    private void ExportToSQLServer(AppDbContext sourceContext, string targetFilePath)
    {
        // 获取所有学生数据
        var students = sourceContext.Students.AsNoTracking().ToList();

        // 生成SQL Server脚本
        var sqlScript = GenerateSQLServerScript(students);

        // 保存为SQL文件
        File.WriteAllText(targetFilePath, sqlScript);
    }

    private void ExportToMySQL(AppDbContext sourceContext, string targetFilePath)
    {
        // 获取所有学生数据
        var students = sourceContext.Students.AsNoTracking().ToList();

        // 生成MySQL脚本
        var sqlScript = GenerateMySQLScript(students);

        // 保存为SQL文件
        File.WriteAllText(targetFilePath, sqlScript);
    }

    private void ExportToCSV(AppDbContext sourceContext, string targetFilePath)
    {
        // 获取所有学生数据
        var students = sourceContext.Students.AsNoTracking().ToList();

        // 生成CSV内容
        var csvContent = GenerateCSVContent(students);

        // 保存为CSV文件
        File.WriteAllText(targetFilePath, csvContent, Encoding.UTF8);
    }

    private void ExportToJSON(AppDbContext sourceContext, string targetFilePath)
    {
        // 获取所有学生数据
        var students = sourceContext.Students.AsNoTracking().ToList();

        // 序列化为JSON
        var jsonContent = JsonSerializer.Serialize(students, new JsonSerializerOptions
        {
            WriteIndented = true,
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase
        });

        // 保存为JSON文件
        File.WriteAllText(targetFilePath, jsonContent, Encoding.UTF8);
    }

    private string GenerateSQLServerScript(List<Student> students)
    {
        var sb = new StringBuilder();

        // 添加表创建语句
        sb.AppendLine("IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='Students' AND xtype='U')");
        sb.AppendLine("CREATE TABLE Students (");
        sb.AppendLine("    Id NVARCHAR(8) PRIMARY KEY,");
        sb.AppendLine("    Name NVARCHAR(50) NOT NULL,");
        sb.AppendLine("    College NVARCHAR(100),");
        sb.AppendLine("    Department NVARCHAR(100),");
        sb.AppendLine("    Class NVARCHAR(50),");
        sb.AppendLine("    Dormitory NVARCHAR(50),");
        sb.AppendLine("    Hometown NVARCHAR(100),");
        sb.AppendLine("    Phone NVARCHAR(20)");
        sb.AppendLine(");");
        sb.AppendLine();

        // 添加插入语句
        foreach (var student in students)
        {
            sb.AppendLine("INSERT INTO Students (Id, Name, College, Department, Class, Dormitory, Hometown, Phone, CreatedAt, UpdatedAt)");
            sb.AppendLine($"VALUES ('{EscapeSqlValue(student.Id)}', '{EscapeSqlValue(student.Name)}', '{EscapeSqlValue(student.College)}',");
            sb.AppendLine($"        '{EscapeSqlValue(student.Department)}', '{EscapeSqlValue(student.Class)}', '{EscapeSqlValue(student.Dormitory)}',");
            sb.AppendLine($"        '{EscapeSqlValue(student.Hometown)}', '{EscapeSqlValue(student.Phone)}'");
            sb.AppendLine();
        }

        return sb.ToString();
    }

    private string GenerateMySQLScript(List<Student> students)
    {
        var sb = new StringBuilder();

        // 添加表创建语句
        sb.AppendLine("CREATE TABLE IF NOT EXISTS Students (");
        sb.AppendLine("    Id VARCHAR(8) PRIMARY KEY,");
        sb.AppendLine("    Name VARCHAR(50) NOT NULL,");
        sb.AppendLine("    College VARCHAR(100),");
        sb.AppendLine("    Department VARCHAR(100),");
        sb.AppendLine("    Class VARCHAR(50),");
        sb.AppendLine("    Dormitory VARCHAR(50),");
        sb.AppendLine("    Hometown VARCHAR(100),");
        sb.AppendLine("    Phone VARCHAR(20),");
        sb.AppendLine("    CreatedAt DATETIME,");
        sb.AppendLine("    UpdatedAt DATETIME");
        sb.AppendLine(");");
        sb.AppendLine();

        // 添加插入语句
        foreach (var student in students)
        {
            sb.AppendLine("INSERT INTO Students (Id, Name, College, Department, Class, Dormitory, Hometown, Phone, CreatedAt, UpdatedAt)");
            sb.AppendLine($"VALUES ('{EscapeSqlValue(student.Id)}', '{EscapeSqlValue(student.Name)}', '{EscapeSqlValue(student.College)}',");
            sb.AppendLine($"        '{EscapeSqlValue(student.Department)}', '{EscapeSqlValue(student.Class)}', '{EscapeSqlValue(student.Dormitory)}',");
            sb.AppendLine($"        '{EscapeSqlValue(student.Hometown)}', '{EscapeSqlValue(student.Phone)}'");
            sb.AppendLine();
        }

        return sb.ToString();
    }

    private string GenerateCSVContent(List<Student> students)
    {
        var sb = new StringBuilder();

        // 添加标题行
        sb.AppendLine("学号,姓名,学院,系,班级,宿舍,籍贯,电话,创建时间,更新时间");

        // 添加数据行
        foreach (var student in students)
        {
            sb.AppendLine($"\"{EscapeCsvValue(student.Id)}\",\"{EscapeCsvValue(student.Name)}\",\"{EscapeCsvValue(student.College)}\",");
            sb.AppendLine($"\"{EscapeCsvValue(student.Department)}\",\"{EscapeCsvValue(student.Class)}\",\"{EscapeCsvValue(student.Dormitory)}\",");
            sb.AppendLine($"\"{EscapeCsvValue(student.Hometown)}\",\"{EscapeCsvValue(student.Phone)}\"");
        }

        return sb.ToString();
    }

    private string EscapeSqlValue(string value)
    {
        if (string.IsNullOrEmpty(value)) return "";
        return value.Replace("'", "''");
    }

    private string EscapeCsvValue(string value)
    {
        if (string.IsNullOrEmpty(value)) return "";
        return value.Replace("\"", "\"\"");
    }


    #region 线程安全与性能优化
    private T ExecuteWithPerformanceMonitoring<T>(Func<T> operation)
    {
        var watch = System.Diagnostics.Stopwatch.StartNew();
        try
        {
            return operation();
        }
        finally
        {
            watch.Stop();
            // 实际项目中可添加性能日志记录
            // Debug.WriteLine($"操作耗时: {watch.ElapsedMilliseconds}ms");
        }
    }

    private void ExecuteWithConcurrencyControl(Action operation)
    {
        lock (_context)
        {
            operation();
        }
    }
    #endregion
}